package com.wngbms.homework.config;

import com.wngbms.homework.annotation.TypeHandler;
import com.wngbms.homework.bean.B4;
import com.wngbms.homework.util.TypeHandlerFactory;
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ImportSelector;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.core.type.filter.AnnotationTypeFilter;
import org.springframework.core.type.filter.AssignableTypeFilter;

import java.util.HashSet;
import java.util.Map;
import java.util.Set;

public class AnnotationSelector implements ImportSelector {

//    @Override
//    public String[] selectImports(AnnotationMetadata importingClassMetadata) {
//        Map<String, Object> annotationAttributes = importingClassMetadata.getAnnotationAttributes(ComponentScan.class.getName());
//        String[] basePackages = (String[]) annotationAttributes.get("basePackages");
//
//        ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(false);
//        scanner.addIncludeFilter(new AssignableTypeFilter(B4.class));
//
//        Set<String> classes = new HashSet<>();
//        for (String basePackage : basePackages) {
//            scanner.findCandidateComponents(basePackage).forEach(beanDefinition -> classes.add(beanDefinition.getBeanClassName()));
//        }
//
//        return classes.toArray(new String[classes.size()]);
//    }

//    @Override
//    public String[] selectImports(AnnotationMetadata importingClassMetadata) {
//        String packageName = null;
//        try {
//            packageName = Class.forName(importingClassMetadata.getClassName()).getPackage().getName();
//        } catch (ClassNotFoundException e) {
//            e.printStackTrace();
//        }
//
//        String[] basePackages = new String[]{packageName};
//
//        ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(false);
//        scanner.addIncludeFilter(new AssignableTypeFilter(B4.class));
//
//        Set<String> classes = new HashSet<>();
//        for (String basePackage : basePackages) {
//            scanner.findCandidateComponents(basePackage).forEach(beanDefinition -> classes.add(beanDefinition.getBeanClassName()));
//        }
//
//        return classes.toArray(new String[classes.size()]);
//    }

    @Override
    public String[] selectImports(AnnotationMetadata importingClassMetadata) {
        Map<String, Object> annotationAttributes = importingClassMetadata.getAnnotationAttributes(ComponentScan.class.getName());
        String[] basePackages = (String[]) annotationAttributes.get("basePackages");

        ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(false);
        scanner.addIncludeFilter(new AnnotationTypeFilter(TypeHandler.class));

        Set<String> classes = new HashSet<>();
        for (String basePackage : basePackages) {
            scanner.findCandidateComponents(basePackage).forEach(beanDefinition -> {
                try {
                    Class<?> aClass = Class.forName(beanDefinition.getBeanClassName());
                    TypeHandler annotation = aClass.getAnnotation(TypeHandler.class);
                    if (annotation != null) {
                        String value = annotation.value();
                        TypeHandlerFactory.typeHandlerMap.put(value, aClass);
                    }
                } catch (ClassNotFoundException e) {
                    e.printStackTrace();
                }
                classes.add(beanDefinition.getBeanClassName());
            });
        }

        return classes.toArray(new String[classes.size()]);
    }

}
